package com.shuqi.bookcontent;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextUtils;

import com.shuqi.application.ShuqiApplication;
import com.shuqi.common.Constant;
import com.shuqi.common.utils.Util;
import com.shuqi.controller.R;
import com.shuqi.model.bean.BookContentLineInfo;
import com.shuqi.model.encoding.GBKEncoding;
import com.shuqi.model.encoding.IEncoding;
import com.shuqi.model.encoding.UTF8Encoding;

/**
 * 内容的绘制,对数据的拆分排版,设置文字的X,Y坐标
 * 
 * @author Jianda.Yang
 * 
 * @Date 2014-6-4 上午10:35:26
 */
public class BookContentRender {

    public interface IBookContentRenderSetting {
        int getMarginLeft();

        int getMarginTop();

        int getTopTextSize();

        int getTopToTitle();

        float getLineSpace();

        int getDefaultBackgroundColor();

        int getBackGroundColorFromTheme(int themeid);

        float getDensity();

        int getScreenWidth();

        int getScreenHeight();

        int getSideWidth();

        int getMarginRight();

        int getTextSize();

        int resetBuyButtonResId();

        int getBuyButtonTextColor();

        int getmPageTurnMode();

        int getmTitleSpace();

        int getmParagraphSpace();

        int getmTitleTextSize();

        int getMarginBottom();

        int getmBatteryHeight();

        int getStatusBarHeight();

    }

    private final IBookContentRenderSetting mBookContentRenderSetting;

    private final BookContentPaint mPaint;

    private String mBookName;

    private Bitmap mBackgroundBitmap;
    private int mThemeId = 0;

    private final int IMG_W;
    private final int IMG_H;

    /** 对应字符串中的book_content_button_text_array的索引 */
    public static final int BOOK_COTNENT_BUTTON_TEXT_BUY = 0;
    public static final int BOOK_CONTENT_BUTTON_TEXT_COVER = 1;
    public static final int BOOK_CONTENT_BUTTON_TEXT_RETRY = 2;
    public static final int BOOK_CONTENT_BUTTON_TEXT_LOGIN = 3;

    private Context mContext;

    private int mTitleDianDianDianLength = 0;

    private static final String DIANDIANDIAN = "...";
    private static final String BLANK = "　";
    /** 半角空格 */
    private static final String BLANL_SEMIANGLE = " ";
    String s = "\\s";// A3A0
    /** 段首缩进字符长度 */
    private static final int INDENT_LENGTH = 2;
    /** 段首缩进字符，默认四个空格 */
    public static final String INDENT_STRING = "    ";

    /** 段间距标识 */
    public static final String PARAGRAPH_SPACE = "sq|pgh";

    /** (自由模式)拖动模式的偏移量(>=textsize+linespace)(<=0) */
    public float mScrollOffset = 0;

    private List<BookContentLineInfo> copyContentList;

    public BookContentRender(IBookContentRenderSetting settings) {

        mContext = ShuqiApplication.getContext().getApplicationContext();

        mPaint = new BookContentPaint();

        mBookContentRenderSetting = settings;

        // TITLE_MARGIN_TOP = (int) (205.33f * settings.getDensity());
        // TOAST_MARGIN_TOP = (int) (17.33 * settings.getDensity());
        // IMG_W = (int) (139f * settings.getDensity());
        // IMG_H = (int) (45 * settings.getDensity());

        IMG_W = mContext.getResources().getDimensionPixelSize(R.dimen.page_pay_button_width);
        IMG_H = mContext.getResources().getDimensionPixelSize(R.dimen.page_pay_button_height);

        init();
    }

    private void init() {
        initErrorChar();
    }

    /** 首行不能包含的字符集合 */
    private static Set<Character> errorChar = new HashSet<Character>();

    /** 初始化首行不能显示的标点集合 */
    private void initErrorChar() {
        errorChar.add(',');
        errorChar.add('.');
        errorChar.add('!');
        errorChar.add('?');
        errorChar.add(':');
        errorChar.add(')');
        errorChar.add('"');
        errorChar.add('，');
        errorChar.add('。');
        errorChar.add('、');
        errorChar.add('！');
        errorChar.add('？');
        errorChar.add('：');
        errorChar.add('》');
        errorChar.add('”');
        errorChar.add('~');
        errorChar.add('>');
    }

    public void setTitle(String titleName) {
        mBookName = titleName;
    }

    /**
     * 用画笔 画出背景
     * 
     * @param canvas
     */
    private void drawBackground(Canvas canvas) {
        if (mBackgroundBitmap == null || mBackgroundBitmap.isRecycled()) {
            canvas.drawColor(mBookContentRenderSetting.getBackGroundColorFromTheme(this.mThemeId));
            // canvas.drawColor(mBookContentRenderSetting.getDefaultBackgroundColor());
        } else {
            if (!mBackgroundBitmap.isRecycled()) {
                // 9.3.9将背景设置为图片，将小图片拼接
                int width = mBackgroundBitmap.getWidth();
                int height = mBackgroundBitmap.getHeight();

                float scaleWidth = ((float) mBookContentRenderSetting.getScreenWidth()) / width;
                float scaleHeight = ((float) mBookContentRenderSetting.getScreenHeight()) / height;
                for (int i = 0; i < scaleWidth + 1; i++) {
                    for (int j = 0; j < scaleHeight + 1; j++) {
                        canvas.drawBitmap(mBackgroundBitmap, i * width, j * height, null);
                    }
                }
                // 之前用一整张大的图片，根据屏幕大小进行了拉伸
                // canvas.drawBitmap(mBackgroundBitmap, 0, 0, null);
            } else {
                canvas.drawColor(mBookContentRenderSetting.getDefaultBackgroundColor());
            }
        }
    }

    /**
     * 重置为 所限定的背景图片
     * 
     * @param bmp
     */
    public void resetBackground(Bitmap bmp) {
        destoryBackground();
        this.mBackgroundBitmap = bmp;
    }

    /**
     * 设置主题
     * 
     * @param themeId
     */
    public void setBgThemeId(int themeId) {
        this.mThemeId = themeId;
    }

    /**
     * 销毁背景图片
     */
    public void destoryBackground() {
        if (mBackgroundBitmap != null && !mBackgroundBitmap.isRecycled()) {
            mBackgroundBitmap.recycle();
            mBackgroundBitmap = null;
        }
    }

    /**
     * 用画笔 来画顶部的章节信息
     * 
     * @param canvas
     */
    private void drawTop(Canvas canvas) {

        mPaint.changeStyleToTop();

        if (mBookName != null && mBookName.length() > 0) {

            if (mTitleDianDianDianLength == 0) {
                mTitleDianDianDianLength = getStringWidth(mPaint, DIANDIANDIAN);
            }

            final int screenWidth =
                    mBookContentRenderSetting.getScreenWidth()
                            - mBookContentRenderSetting.getMarginLeft()
                            - mBookContentRenderSetting.getMarginRight() - mTitleDianDianDianLength;

            final String tmpStr = getLineString(mPaint, mBookName, screenWidth);

            canvas.drawText(tmpStr, mBookContentRenderSetting.getMarginLeft(),
                    mBookContentRenderSetting.getMarginTop(), mPaint);
        }
    }

    /**
     * 获取字符串宽度
     * 
     * @param paint
     * @param str
     * @return
     */
    public int getStringWidth(Paint paint, String str) {
        int iRet = 0;
        if (str != null && str.length() > 0) {
            int len = str.length();
            float[] widths = new float[len];
            paint.getTextWidths(str, widths);
            for (int j = 0; j < len; j++) {
                iRet += (int) Math.ceil(widths[j]);
            }
        }
        return iRet;
    }

    /**
     * 调整字符串长度，保证其不长于屏幕宽度
     * 
     * @param paint
     * @param str
     * @param screenWidth
     * @return
     */
    private String getLineString(Paint paint, String str, int screenWidth) {
        int iRet = 0;
        if (str != null && str.length() > 0) {
            int len = str.length();
            float[] widths = new float[len];
            paint.getTextWidths(str, widths);
            for (int j = 0; j < len; j++) {
                iRet += (int) Math.ceil(widths[j]);

                if (iRet >= screenWidth) {
                    return str.substring(0, j) + DIANDIANDIAN;
                }
            }
        }
        return str;
    }

    /**
     * 画正文的文字
     * 
     * @param canvas
     * @param content
     * @param xys 每个字符的位置坐标
     */
    private void drawContent(Canvas canvas, String content, float[] xys) {
        canvas.drawPosText(content, xys, mPaint);
    }

    /****
     * 
     * 绘制正文页面
     * 
     * @param canvas
     * @param lineNum
     * @param lineIndex
     * @param curLines
     * @param nextLines
     * @param preLines
     */
    public void drawReadStateNormalCanvas(Canvas canvas, int lineNum, int lineIndex,
            List<BookContentLineInfo> curLines, List<BookContentLineInfo> nextLines,
            List<BookContentLineInfo> preLines, int byteIndex, boolean actionDirection,
            boolean isChangeIndex, boolean isJumpChapter, boolean isRefreshIndex) {

        drawEmptyView(canvas);

        drawNormalText(canvas, lineNum, lineIndex, curLines, nextLines, preLines, byteIndex,
                actionDirection, isChangeIndex, isJumpChapter, isRefreshIndex);
    }


    private final static String TAG_DRAW = "draw";

    /**
     * 计算首行起始LineIndex
     * 
     * @param byteIndex 读取到的字节索引
     * @param curLines
     * @return
     */
    private int startReadIndex(int byteIndex, List<BookContentLineInfo> curLines) {
        int readIndex = 0;
//        Log4an.d(TAG_DRAW, "【startReadIndex】byteIndex=" + byteIndex + ",curLines.size()="
//                + curLines.size() + ",mCurLinesFirstIndex=" + getmCurLinesFirstByteIndex());
        if (byteIndex < 0) {
            byteIndex = getmCurLinesFirstByteIndex();
        }
        for (int i = 0; i < curLines.size() - 1; i++) {
            if (i == 0) {
                String str = curLines.get(i).getContent();
                if (!PARAGRAPH_SPACE.equals(str)) {
                    setmCurLinesFirstByteIndex(curLines.get(i).getFirstIndex());
                } else {
                    setmCurLinesFirstByteIndex(curLines.get(i + 1).getFirstIndex());
                }
            }
            if (byteIndex >= curLines.get(i).getFirstIndex()
                    && byteIndex <= curLines.get(i).getEndIndex()) {
                if (byteIndex == curLines.get(i).getEndIndex()) {
                    readIndex = i + 1;
//                    Log4an.e(TAG_DRAW, "2.readIndex=" + readIndex + ","
//                            + curLines.get(readIndex).getContent());

                    break;
                }
                if (byteIndex >= curLines.get(i).getFirstIndex()) {
                    readIndex = i;
//                    Log4an.e(TAG_DRAW, "3.readIndex=" + readIndex + ","
//                            + curLines.get(readIndex).getContent());
//                    if (TextUtils.isEmpty(curLines.get(readIndex).getContent())) {
//                        Log4an.e(TAG_DRAW,
//                                "4.readIndex=" + readIndex + ","
//                                        + curLines.get(readIndex).getContent());
//                    }

                    if (PARAGRAPH_SPACE.equals(curLines.get(readIndex).getContent())) {
                        readIndex = i + 1;
//                        Log4an.e(TAG_DRAW,
//                                "5.readIndex=" + readIndex + ","
//                                        + curLines.get(readIndex).getContent());
                    }

                    if (!TextUtils.isEmpty(firstLineInfo)
                            && !TextUtils.isEmpty(curLines.get(readIndex).getContent())
                            && firstLineInfo.length() > 2
                            && curLines.get(readIndex).getContent().length() > 2
                            && !curLines.get(readIndex).getContent().substring(0, 2)
                                    .contains(firstLineInfo.substring(0, 2))) {
                        readIndex = i;
//                        Log4an.e(TAG_DRAW, "firstLineInfo=" + firstLineInfo + ",curinfo="
//                                + curLines.get(readIndex).getContent() + ",readIndex=" + readIndex);
                    }
                    break;
                }
            }
        }
//        Log4an.e(TAG_DRAW, "readIndex=" + readIndex);
//        Log4an.e("draw", "当前数据首行字节索引=" + getmCurLinesFirstByteIndex());
        // for (int i = 0; i < curLines.size(); i++) {
        // Log4an.i("yyy", "【curLines】" + curLines.get(i).getContent() + ",i=" + i + ",start="
        // + curLines.get(i).getFirstIndex() + ",end=" + curLines.get(i).getEndIndex());
        // }
        return readIndex;
    }

    /**
     * 绘制区域宽度
     * 
     * @return
     */
    private int viewWidth() {
        int w =
                mBookContentRenderSetting.getScreenWidth()
                        - mBookContentRenderSetting.getMarginLeft()
                        - mBookContentRenderSetting.getMarginRight()
                        - mBookContentRenderSetting.getSideWidth();
        // Log4an.i(TAG, "绘制区域宽度: " + w + ",屏幕宽度：" + mBookContentRenderSetting.getScreenWidth());
        // Log4an.e("yyy",
        // "【viewWidth】" + w + ",screenW=" + mBookContentRenderSetting.getScreenWidth()
        // + ",left=" + mBookContentRenderSetting.getMarginLeft() + ",right="
        // + mBookContentRenderSetting.getMarginRight() + ",side="
        // + mBookContentRenderSetting.getSideWidth());
        return w;
    }

    /**
     * 绘制区域高度
     * 
     * @return
     */
    private int viewHeight() {
        int h = 0;
        // Log4an.i(TAG_DRAW, "getScreenHeight=" + mBookContentRenderSetting.getScreenHeight()
        // + ",getMarginTop=" + mBookContentRenderSetting.getMarginTop() + ",getMarginBottom="
        // + mBookContentRenderSetting.getMarginBottom() + ",getmBatteryHeight="
        // + mBookContentRenderSetting.getmBatteryHeight() + ",getStatusBarHeight="
        // + mBookContentRenderSetting.getStatusBarHeight());
        h =
                mBookContentRenderSetting.getScreenHeight()
                        - mBookContentRenderSetting.getMarginTop()
                        - mBookContentRenderSetting.getMarginBottom()
                        - mBookContentRenderSetting.getmBatteryHeight()
                        - mBookContentRenderSetting.getStatusBarHeight();
        // Log4an.i(TAG_DRAW, "绘制区域高度: " + h + ",屏幕高度：" +
        // mBookContentRenderSetting.getScreenHeight()
        // + ",通知栏高度：" + mBookContentRenderSetting.getStatusBarHeight());
        return h;
    }

    /** 上一页首行索引 */
    int preReadIndex = -1;
    /** 当前页首行索引 */
    int curReadIndex = 0;
    /** 下一页首行索引 */
    int nextReadIndex = -1;

    /** 重置首行索引 */
    private void resetReadIndex() {
        preReadIndex = -1;
        curReadIndex = 0;
        nextReadIndex = -1;
    }

    private void logReadIndex(String tag) {
//        Log4an.e(TAG_DRAW, "【" + tag + "】" + "preReadIndex=" + preReadIndex + ",curReadIndex="
//                + curReadIndex + ",nextReadIndex=" + nextReadIndex);
    }

    /** 当前屏幕首行起始索引 */
    private int firstLineIndex = 0;// 行索引
    /** 当前屏幕首行首字符字节索引 */
    private int firstByteIndex = 0;// 当前页首字符索引(供model使用)
    /** 当前屏幕的最后索引 */
    /** 当前屏幕首行首行内容 */
    private String firstLineInfo = null;
    /** 当前页行数 */
    int curLineNum = 0;

    /** 提供外部当前数据的第一行的字节索引 */
    private int mCurLinesFirstByteIndex = 0;// 用于改变字体等使用

    /**
     * @return the mCurLinesFirstByteIndex
     */
    public int getmCurLinesFirstByteIndex() {
        return mCurLinesFirstByteIndex;
    }

    /**
     * @param mCurLinesFirstByteIndex the mCurLinesFirstByteIndex to set
     */
    public void setmCurLinesFirstByteIndex(int mCurLinesFirstByteIndex) {
        this.mCurLinesFirstByteIndex = mCurLinesFirstByteIndex;
    }

    /**
     * @return the firstLineIndex
     */
    public int getFirstLineIndex() {
        return firstLineIndex;
    }

    /**
     * @return the curLineNum
     */
    public int getCurLineNum() {
        return curLineNum;
    }



    /**
     * @return the firstByteIndex
     */
    public int getFirstByteIndex() {
        return firstByteIndex;
    }

    int changeCurLineSize = 0;// 用于章节切换数据时首行索引是否重置的判断
    int changeChapterToChangeIndex = -1;// 更换章节时，更换索引(用于当前章节最后一页和下章第一页情况)
    /** 当前页碰到标记的次数 */
    int tagCount = 0;// 每次绘制当前页时，都要重置为0


    /**
     * @return the tagCount
     */
    public int getTagCount() {
        return tagCount;
    }

    /** 是否更改了setting属性 */
    private boolean isNotifyChangeSetting = false;


    /**
     * @return the isNotifyChangeSetting
     */
    public boolean isNotifyChangeSetting() {
        return isNotifyChangeSetting;
    }

    /**
     * @param isNotifyChangeSetting the isNotifyChangeSetting to set
     */
    public void setNotifyChangeSetting(boolean isNotifyChangeSetting) {
        this.isNotifyChangeSetting = isNotifyChangeSetting;
    }

    /** 初始化当前页 */
    private boolean isInitcurPage = true;

    private boolean isChangeCurLineSize = false;



    /**
     * @param isChangeCurLineSize the isChangeCurLineSize to set
     */
    public void setChangeCurLineSize(boolean isChangeCurLineSize) {
        this.isChangeCurLineSize = isChangeCurLineSize;
    }

    /**
     * 
     * @param canvas
     * @param lineNum
     * @param lineIndex
     * @param curLines
     * @param nextLines
     * @param preLines
     * @param byteIndex 读取到的字节索引
     * @param actionDirection 方向
     * @param isChangeIndex 是否改变索引(true:改变；false：不改变)
     * @param isJumpChapter 是否是跳章逻辑
     * @param isRefreshIndex 是否刷新数据(从异常情况进入到正文内容)
     */
    private void drawNormalText(Canvas canvas, int lineNum, int lineIndex,
            List<BookContentLineInfo> curLines, List<BookContentLineInfo> nextLines,
            List<BookContentLineInfo> preLines, int byteIndex, boolean actionDirection,
            boolean isChangeIndex, boolean isJumpChapter, boolean isRefreshIndex) {
//        Log4an.e(TAG_DRAW, "【drawNormalText】" + "actionDirection=" + actionDirection
//                + ",isChangeIndex=" + isChangeIndex + ",isJumpChapter=" + isJumpChapter
//                + ",byteIndex=" + byteIndex + ",isRefreshIndex=" + isRefreshIndex);
        if (curLines == null) {
            return;
        }
        if (copyContentList == null) {
            copyContentList = new ArrayList<BookContentLineInfo>();
        } else {
            copyContentList.clear();
        }

        // 控制跳章逻辑(目录点击、上下章按钮点击)
        if (isJumpChapter) {
            resetReadIndex();
            changeCurLineSize = 0;
            changeChapterToChangeIndex = 0;
            isInitcurPage = true;
            tPreCount = -1;
            byteIndex = 0;
            firstLineInfo = null;
        }

        // 从异常(重试或购买)向前翻页到有缓存章节时
        if (isRefreshIndex) {
            changeChapterToChangeIndex = 2;
            isInitcurPage = true;
            changeCurLineSize = 1;
        }

        int curLineSize = curLines.size();// 默认值
        final int viewH = viewHeight();
        final int spaceFailover = mBookContentRenderSetting.getTextSize() / 3;
//        Log4an.i(TAG_DRAW, "【切换章节判断条件】changeCurLineSize=" + changeCurLineSize + ",curLineSize="
//                + curLineSize + ",isChangeCurLineSize=" + isChangeCurLineSize);

        // 当遇到本章与下章或上章数据大小相同时
        if (isChangeCurLineSize && changeCurLineSize != 0 && changeCurLineSize == curLineSize) {
            changeCurLineSize--;
//            Log4an.i(TAG_DRAW, "【遇到两章相等情况了】changeCurLineSize=" + changeCurLineSize);
        }

        // 换章索引处理
        if (!isNotifyChangeSetting() && changeCurLineSize != 0 && changeCurLineSize != curLineSize) {
//            Log4an.i(TAG_DRAW, "【切换章节】changeChapterToChangeIndex=" + changeChapterToChangeIndex);
            if (changeChapterToChangeIndex == 1) {
                preReadIndex = curReadIndex;
                curReadIndex = nextReadIndex != -1 ? nextReadIndex : 0;
                nextReadIndex = 0;
                logReadIndex("切换章节");
            } else if (changeChapterToChangeIndex == 2) {
                if (!isInitcurPage) {
                    isInitcurPage = true;
                }
                if (curLines != null && curLines.size() > 0) {
                    final int contentTextSize = mBookContentRenderSetting.getTextSize();
                    int textSize = contentTextSize;
                    int preY =
                            mBookContentRenderSetting.getMarginTop()
                                    + mBookContentRenderSetting.getTextSize()
                                    + mBookContentRenderSetting.getTopToTitle();
                    int preCurIndex = curLines.size() - 1;// 上一页当前
                    int tempIndex = preCurIndex;
                    for (int i = preCurIndex; i > 0; i--) {
                        BookContentLineInfo preInfo = getBookContentLineInfo(preCurIndex, curLines);
                        // Log4an.i(TAG_DRAW, "【切章预排】preInfo=" + preInfo.getContent()
                        // + ",preCurIndex=" + preCurIndex);
                        if (preInfo != null) {
                            int space = (int) mBookContentRenderSetting.getLineSpace();
                            String str = preInfo.getContent();
                            if (PARAGRAPH_SPACE.equals(str)) {
                                str = "";
                                if (i != tempIndex) {
                                    space = mBookContentRenderSetting.getmParagraphSpace();
                                } else {
                                    space = -mBookContentRenderSetting.getmParagraphSpace();
                                }
                            }
                            setAllLineY(preInfo.getXys(), preY);

                            preY += textSize + space;
                            preCurIndex--;
                            if (preCurIndex == -1) {
                                preReadIndex = 0;
                            }
                            // 当前数据绘制超过一屏
                            if (preY - textSize > viewH) {
                                int prePrePageLineNum =
                                        curLines.size() - (tempIndex - (preCurIndex + 1));
                                // Log4an.i(TAG_DRAW, "[超过屏幕]preCurIndex=" + preCurIndex + ",差值="
                                // + prePrePageLineNum);
                                if (prePrePageLineNum > 5) {
                                    preReadIndex = preCurIndex + 1;
                                    // Log4an.i(TAG_DRAW, "preReadIndex=" + preReadIndex);
                                    if (preCurIndex < 5) {
                                        preReadIndex = 0;
                                    }
                                    logReadIndex("预排");
                                    curReadIndex = preReadIndex;
                                    nextReadIndex = 0;
                                }
                                logReadIndex("切换章节预排上页索引");
                                break;
                            }
                            preInfo = null;
                        }

                    }
                    resetNextIndex = 0;
                }
            }
            changeChapterToChangeIndex = 0;
            isChangeCurLineSize = false;
        }
        changeCurLineSize = curLineSize;

        // 改变字体等属性时
        if (isNotifyChangeSetting()) {
            resetReadIndex();
//            Log4an.i(TAG_DRAW, "【改变setting属性】mCurLinesFirstByteIndex=" + mCurLinesFirstByteIndex
//                    + ",firstByteIndex=" + firstByteIndex);
            byteIndex = firstByteIndex;
            isInitcurPage = true;
            tPreCount = -1;
//            Log4an.i(TAG_DRAW, "【改变setting属性】byteIndex=" + byteIndex);
        }
//        Log4an.i(TAG_DRAW, "【drawNormalText】curLineSize=" + curLineSize + ",lineIndex=" + lineIndex
//                + ",byteIndex=" + byteIndex + ",actionDirection=" + actionDirection + ",isNotify="
//                + isNotifyChangeSetting() + ",isInitcurPage=" + isInitcurPage);

        // 初始化当前索引
        if (isInitcurPage) {
            if (!isJumpChapter) {
                curReadIndex = startReadIndex(byteIndex, curLines);
            } else {
                curReadIndex = 0;
            }
//            Log4an.i(TAG_DRAW, "【startReadIndex】curReadIndex=" + curReadIndex
//                    + ",changeChapterToChangeIndex=" + changeChapterToChangeIndex);
            nextReadIndex = -1;
            logReadIndex("初始化");
            isInitcurPage = false;
        }

        if (curLineSize > 0) {
            mPaint.changeStyleToContent();
            int y =
                    mBookContentRenderSetting.getMarginTop()
                            + mBookContentRenderSetting.getTextSize()
                            + mBookContentRenderSetting.getTopToTitle();
            // Log4an.i(TAG_DRAW, "【y】=" + y);

            final int contentTextSize = mBookContentRenderSetting.getTextSize();
            final int lineSpace = (int) mBookContentRenderSetting.getLineSpace();
            int textSize = contentTextSize;

            if (!isNotifyChangeSetting()) {
                if (actionDirection) {// 向后翻页
                    if (!isChangeIndex) {
                        logReadIndex("1");
                    } else {
//                        Log4an.e(TAG_DRAW, "【向后翻页】nextReadIndex=" + nextReadIndex);
                        if (nextReadIndex != -1) {
//                            Log4an.e(TAG_DRAW, "【1A】preReadIndex=" + preReadIndex
//                                    + ",curReadIndex=" + curReadIndex + ",nextReadIndex="
//                                    + nextReadIndex);

                            preReadIndex = curReadIndex;
                            curReadIndex = nextReadIndex;
                            nextReadIndex = -1;

//                            Log4an.e(TAG_DRAW, "【2A】preReadIndex=" + preReadIndex
//                                    + ",curReadIndex=" + curReadIndex + ",nextReadIndex="
//                                    + nextReadIndex);
                            logReadIndex("2");
                        }
                    }
                } else {// 向前翻页
                    logReadIndex("***切换章节***");
                    if (!isChangeIndex) {// 初始化
                        logReadIndex("3");
                    } else {
//                        Log4an.e(TAG_DRAW, "【向前翻页】preReadIndex" + preReadIndex);
                        if (preReadIndex != -1) {
//                            Log4an.e(TAG_DRAW, "【1A】preReadIndex=" + preReadIndex
//                                    + ",curReadIndex=" + curReadIndex + ",nextReadIndex="
//                                    + nextReadIndex);

                            nextReadIndex = curReadIndex;
                            curReadIndex = preReadIndex;
                            preReadIndex = 0;

//                            Log4an.e(TAG_DRAW, "【2A】preReadIndex=" + preReadIndex
//                                    + ",curReadIndex=" + curReadIndex + ",nextReadIndex="
//                                    + nextReadIndex);
                        }
                        logReadIndex("4");
                    }
                }
            }
            // 解决拖动条处理时,数组越界问题
            if (curReadIndex >= curLineSize) {
                resetReadIndex();
                curReadIndex = curLineSize - 30;
                tPreCount = -1;
            }
            tagCount = 0;
            boolean parageraphTag = false;// 第一行遇到段落或标题标记
            /* 处理当前绘制页面 */
            for (int i = 0; i < curLineSize; i++) {
                BookContentLineInfo curInfo = getBookContentLineInfo(curReadIndex + i, curLines);
                if (curInfo != null) {
                    int space = textSize + lineSpace;
                    String str = curInfo.getContent();
                    // Log4an.e(
                    // TAG_DRAW,
                    // "【draw】str=" + str + ",i=" + i + ",star=" + curInfo.getFirstIndex()
                    // + ",end=" + curInfo.getEndIndex() + ",type="
                    // + curInfo.getLineType());
                    if (i == 0) {
                        firstLineIndex = curReadIndex + i;
                        firstLineInfo = str;
                        firstByteIndex = curInfo.getFirstIndex();
                        // Log4an.d(TAG_DRAW, "1.firstLineIndex=" + firstByteIndex +
                        // ",parageraphTag="
                        // + parageraphTag);
                        if (PARAGRAPH_SPACE.equals(str)) {
                            parageraphTag = true;
                        }
                        if (curReadIndex == 0) {
                            mCurLinesFirstByteIndex = firstByteIndex;
                        }
                        // Log4an.d(TAG_DRAW, "2.firstLineIndex=" + firstLineIndex +
                        // ",firstLineInfo="
                        // + firstLineInfo + ",firstByteIndex=" + firstByteIndex);
                    } else if (i == 1) {
                        if (parageraphTag) {
                            firstLineIndex = curReadIndex + i;
                            firstByteIndex = curInfo.getFirstIndex();
                            firstLineInfo = curInfo.getContent();
                            // Log4an.d(TAG_DRAW, "[第一行]firstLineIndex=" + firstLineIndex
                            // + ",firstLineInfo=" + firstLineInfo + ",firstByteIndex="
                            // + firstByteIndex);
                            parageraphTag = false;
                        }

                    }
                    if (PARAGRAPH_SPACE.equals(str)) {
                        str = "";
                        if (i != 0) {
                            space = mBookContentRenderSetting.getmParagraphSpace();
                        } else {
                            space = 0;
                        }
                        tagCount++;
                    }
                    setAllLineY(curInfo.getXys(), y);
                    y += space;
                    drawContent(canvas, str, curInfo.getXys());
                    copyContentList.add(curInfo);
                    // 当前数据剩余不到一屏
                    if ((curReadIndex + i + 1) >= curLineSize) {
                        curLineNum = curLineSize - curReadIndex;
                        changeChapterToChangeIndex = 0;

                        if (actionDirection) {
                            if ((curReadIndex + curLineNum) >= curLineSize) {
                                changeChapterToChangeIndex = 1;
                                // Log4an.e(TAG_DRAW, "【A已经到当前数据结尾】changeChapterToChangeIndex="
                                // + changeChapterToChangeIndex);
                                resetNextIndex = 0;
                            } else if (curReadIndex == 0) {
                                changeChapterToChangeIndex = 2;
                                // Log4an.e(TAG_DRAW, "【B已经到当前数据结尾】changeChapterToChangeIndex="
                                // + changeChapterToChangeIndex);
                            }
                        } else {
                            if (curReadIndex == 0) {
                                changeChapterToChangeIndex = 2;
                                // Log4an.e(TAG_DRAW, "【C已经到当前数据结尾】changeChapterToChangeIndex="
                                // + changeChapterToChangeIndex);
                            }
                        }

                        // Log4an.e(TAG_DRAW, "【当前数据剩余不到一屏】" + ",curLineNum=" + curLineNum
                        // + ",curLineSize=" + curLineSize + ",curReadIndex=" + curReadIndex
                        // + ",changeChapterToChangeIndex=" + changeChapterToChangeIndex
                        // + ",tagCount=" + tagCount + ",info=" + curInfo.getContent()
                        // + ",endIndex=" + curInfo.getEndIndex());
                        logReadIndex("不到一屏幕");
                        break;
                    }
                    // 当前数据绘制超过一屏
                    if (y - space + spaceFailover > viewH) {
                        // Log4an.e(TAG_DRAW, "(y  - space-spaceFailover)="
                        // + (y - space + spaceFailover) + ",viewH=" + viewH + ",curLineSize="
                        // + curLineSize);
                        nextReadIndex = curReadIndex + i + 1;
                        curLineNum = nextReadIndex - curReadIndex - 1;
                        changeChapterToChangeIndex = 0;
                        if ((curReadIndex + curLineNum) >= curLineSize) {
                            changeChapterToChangeIndex = 1;
                            // Log4an.e(TAG_DRAW, "【A已经到当前数据结尾】changeChapterToChangeIndex="
                            // + changeChapterToChangeIndex);
                        } else if (curReadIndex == 0) {
                            changeChapterToChangeIndex = 2;
                            // Log4an.e(TAG_DRAW, "【B已经到当前数据结尾】changeChapterToChangeIndex="
                            // + changeChapterToChangeIndex);
                        }
                        // Log4an.e(TAG_DRAW, "【超过绘制高度】nextReadIndex=" + nextReadIndex + ",y=" + y
                        // + ",curLineNum=" + curLineNum + ",changeChapterToChangeIndex="
                        // + changeChapterToChangeIndex + ",tagCount=" + tagCount + ",info="
                        // + curInfo.getContent() + ",endIndex=" + curInfo.getEndIndex());
                        logReadIndex("超过一屏幕");
                        break;
                    }
                    curInfo = null;
                }
            }
            logReadIndex("0");

            /* 控制是否要缓存上页首行索引 */
            if ((isChangeIndex && !actionDirection) || tPreCount == -1) {
                // Log4an.i(TAG_DRAW, "【预排上页索引条件】isChangeIndex=" + isChangeIndex +
                // ",actionDirection="
                // + actionDirection + ",tPreCount=" + tPreCount);
                tPreCount = 0;
                if (tPreCount == 0 || tPreCount == 2) {
                    if (curReadIndex != 0) {
                        int preY =
                                mBookContentRenderSetting.getMarginTop()
                                        + mBookContentRenderSetting.getTextSize()
                                        + mBookContentRenderSetting.getTopToTitle();
                        int preCurIndex = curReadIndex - 1;// 上一页当前
                        int tempIndex = curReadIndex - 1;
                        for (int i = preCurIndex; i > -1; i--) {
                            BookContentLineInfo preInfo =
                                    getBookContentLineInfo(preCurIndex, curLines);

                            if (preInfo != null) {
                                int space = textSize + lineSpace;
                                String str = preInfo.getContent();
                                // Log4an.e(TAG_DRAW, "【pre】str=" + str + ",i=" + i);
                                if (PARAGRAPH_SPACE.equals(str)) {
                                    str = "";
                                    if (i != tempIndex) {
                                        space = mBookContentRenderSetting.getmParagraphSpace();
                                    } else {
                                        space = mBookContentRenderSetting.getmParagraphSpace();
                                    }
                                }
                                setAllLineY(preInfo.getXys(), preY);

                                preY += space;
                                preCurIndex--;
                                preReadIndex = preCurIndex;
                                if (preCurIndex == -1) {
                                    preReadIndex = 0;
                                }
                                // 当前数据绘制超过一屏
                                if (preY - space > viewH) {
                                    // Log4an.e(TAG_DRAW, "(preY  -space)=" + (preY - space)
                                    // + ",viewH=" + viewH + ",addIndex=" + addIndex);
                                    preReadIndex = preCurIndex + 1;
                                    if (preCurIndex < 5) {
                                        preReadIndex = 0;
                                    }

                                    // Log4an.e(TAG_DRAW, "【pre超过绘制高度】" + ",preY=" + preY
                                    // + ",preCurIndex=" + preCurIndex + ",preReadIndex="
                                    // + preReadIndex + ",addIndex=" + addIndex);
                                    break;
                                }
                                preInfo = null;
                            }
                        }
                    } else {
                        preReadIndex = -1;
                        logReadIndex("变换");
                    }
                    tPreCount = 0;
                }
                tPreCount++;
            }
            // Log4an.e(TAG_DRAW, "1.resetNextIndex=" + resetNextIndex);
            if (resetNextIndex == 0 && ((curReadIndex + curLineNum >= curLineSize))) {
                resetNextIndex = 1;
            }
            // Log4an.e(TAG_DRAW, "2.resetNextIndex=" + resetNextIndex);
            logReadIndex("最终");
        }
    }

    // TODO
    int resetNextIndex = -1;
    /** 控制draw第二次时，才作上页的索引计算 */
    private int tPreCount = -1;

    /**
     * @return the resetNextIndex
     */
    public int isResetNextIndex() {
        return resetNextIndex;
    }

    private void drawEmptyView(Canvas canvas) {
        drawBackground(canvas);

        drawTop(canvas);
    }

    private BookContentLineInfo getBookContentLineInfo(int index, List<BookContentLineInfo> infoList) {
        if (infoList == null || index < 0 || index >= infoList.size()) {
            return null;
        }
        return infoList.get(index);
    }

    /** 设置每一行字的y坐标 */
    public void setAllLineY(float[] xys, float y) {
        if (xys != null && xys.length > 0) {
            for (int i = 0; i < xys.length; i++) {
                if (i % 2 == 1) {
                    xys[i] = y;
                }
            }
        }
    }

    /***
     * 
     * 绘制订单页面
     * 
     * @param canvas
     * @param title
     * @param payTip
     */
    public void drawReadStatePayCanvas(Canvas canvas, String title, String payTip,
            int buttonTextIndex) {

        drawBackground(canvas);

        int y = drawPayButton(canvas, buttonTextIndex);

        y = drawPayTip(canvas, payTip, y);

        drawPayTitle(canvas, title, y);
    }

    /***
     * 绘制付费按钮
     * 
     * @param canvas
     * @param buttonTextIndex
     */
    private int drawPayButton(Canvas canvas, int buttonTextIndex) {
        int lelf = (mBookContentRenderSetting.getScreenWidth() - IMG_W) / 2;
        int top = (mBookContentRenderSetting.getScreenHeight() - IMG_H) / 3 * 2;
        // Log4an.e("2", "lelf=" + lelf + ",top=" + top);
        Rect rect = new Rect(lelf, top, lelf + IMG_W, top + IMG_H);
        drawNinepath(canvas, mBookContentRenderSetting.resetBuyButtonResId(), rect);

        mPaint.changeStyleToPayButton();

        int btnTextX =
                (int) (mBookContentRenderSetting.getScreenWidth() - mPaint
                        .measureText(getButtonText(buttonTextIndex))) / 2;
        final int textAdjustOffset =
                (int) ((mPaint.getFontMetrics().ascent - mPaint.getFontMetrics().top) - (mPaint
                        .getFontMetrics().bottom - mPaint.getFontMetrics().descent));
        canvas.drawText(getButtonText(buttonTextIndex), btnTextX,
                top + (IMG_H + mPaint.getTextSize()) / 2 - textAdjustOffset, mPaint);

        return rect.top;
    }

    /***
     * 绘制付费按钮上方的提示文案
     * 
     * @param canvas
     * @param payTip
     */
    private int drawPayTip(Canvas canvas, String payTip, int y) {
        mPaint.changeStyleToPayTip();

        final int payTipX =
                (int) (mBookContentRenderSetting.getScreenWidth() - mPaint.measureText(payTip)) / 2;

        final int payTipY =
                y
                        - mContext.getResources().getDimensionPixelSize(
                                R.dimen.page_pay_tip_margin_bottom);

        canvas.drawText(payTip, payTipX, payTipY, mPaint);

        return payTipY - Util.getFontHeight(mPaint.getTextSize());
    }

    /***
     * 获得按钮上面的文字
     * 
     * @param buttonIndex
     * @return
     */
    private String getButtonText(int buttonIndex) {
        return mContext.getResources().getStringArray(R.array.book_content_button_text_array)[buttonIndex];
    }

    /***
     * 
     * 画按钮的.9图片
     * 
     * @param c
     * @param id
     * @param r1
     */
    private void drawNinepath(Canvas c, int id, Rect r1) {
        Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), id);
        NinePatch patch = new NinePatch(bmp, bmp.getNinePatchChunk(), null);
        patch.draw(c, r1);
    }

    /***
     * 绘制下载页面
     * 
     * @param canvas
     * @param title
     */
    public void drawReadStateDownloadCanvas(Canvas canvas, String title) {
        drawBackground(canvas);
        final int y = (mBookContentRenderSetting.getScreenHeight() - IMG_H) / 2;
        drawPayTitle(canvas, title, y);
    }

    /***
     * 
     * 绘制付费的按钮上方的标题
     * 
     * @param canvas
     * @param title
     */
    private void drawPayTitle(Canvas canvas, String title, int y) {
        mPaint.changeStyleToPayTitle();
        if (!TextUtils.isEmpty(title)) {
            int screenWidth = mBookContentRenderSetting.getScreenWidth();
            int oneW = (int) mPaint.measureText("国");
            int txtWidth = (int) mPaint.measureText(title);
            int count = 0, viewCount = 0;
            y -=
                    mContext.getResources().getDimensionPixelSize(
                            R.dimen.page_pay_title_margin_bottom);
            if (txtWidth > screenWidth) {
                int a = (int) txtWidth / screenWidth;
                int b = (int) txtWidth % screenWidth;
                if (b != 0) {
                    count = a + 1;
                } else {
                    count = a;
                }
                viewCount = screenWidth / oneW;

                int length = title.length();
                int index = 0, endIndex = viewCount;
                String s[] = new String[count];
                int height = Util.getFontHeight(21 * mBookContentRenderSetting.getDensity());
                y -= height * (count - 1);
                for (int i = 0; i < count; i++) {
                    endIndex = index + viewCount;
                    if (endIndex >= length) {
                        endIndex = length;
                    }
                    s[i] = title.substring(index, endIndex);
                    index += viewCount;
                    int titleLineOneX = (int) (screenWidth - mPaint.measureText(s[i])) / 2;
                    canvas.drawText(s[i], titleLineOneX, y, mPaint);
                    y += height;
                }
            } else {
                int titleX = (int) (screenWidth - txtWidth) / 2;
                canvas.drawText(title, titleX, y, mPaint);
            }

            // int titleX =
            // (int) (mBookContentRenderSetting.getScreenWidth() - mPaint.measureText(title)) / 2;
            // canvas.drawText(title, titleX, TITLE_MARGIN_TOP, mPaint);
        }
    }

    String reg = "^\\s*([0-9]+\\|)|([【第]\\s*[０-９0-9零一二三四五六七八九十百千万]+\\s*[】书首集卷回章节部]+)";

    /**
     * 判断是否是标题
     * 
     * @remark 用于排版时处理一行文字是否是标题
     * @param s
     * @return
     */
    private boolean isTitle(String s) {
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(s);
        if (s.length() < 20 && matcher.find()) {
            return true;
        }
        return false;
    }

    private static final String TAG = "BookContentRender";

    /**
     * 获取当前行首空格个数
     * 
     * @param strTag
     * @param str
     * @return
     */
    private int getBlankCount(String strTag, String str) {
        int k = 1;
        for (; k < str.length() - 1; k++) {
            if (!strTag.equals(str.substring(k, k + 1))) {
                // Log4an.d(TAG, "【原始getBlankCount】k=" + k + ",str=" + str.substring(k, k + 1));
                if (" ".equals(str.substring(k, k + 1))) {
                    k++;
                }
                // Log4an.d(TAG, "【最终getBlankCount】k=" + k + ",str=" + str.substring(k, k + 1));
                break;
            }
        }
        return k;
    }

    /** 分割字节,保证数据在一行 */
    int divByte = -1;

    /**
     * 从传递过来的字节流中的某一个字节进行前后分行
     * 
     * @throws UnsupportedEncodingException
     * @param list 如果该章已经处理了章节名，则传递包含章节名的list
     * @param data 要排版的数组
     * @param isHeader 是否为标题
     * @param startByte 数组第一个字节的起始索引
     * @param divideByte 数组中要拆分显示的字节索引
     * @param encoding 字节内容的编码
     * @return
     * @throws UnsupportedEncodingException
     */
    public List<BookContentLineInfo> getLineinfosByIndex(List<BookContentLineInfo> list,
            byte[] data, boolean isHeader, int startByte, int divideByte, String encoding,
            int bookType) throws UnsupportedEncodingException {

        if (data == null || data.length < 1)
            return null;
//        Log4an.e(TAG, "【接收】isHeader=" + isHeader + ",startByte=" + startByte + ",divideByte="
//                + divideByte + ",encoding=" + encoding + ",bookType=" + bookType + ",dataLen="
//                + data.length);
        if (list == null)
            list = new ArrayList<BookContentLineInfo>();

        /** [0]需要显示索引之前的内容，[1]需要显示索引之后的内容 */
        String content[] = new String[2];
        boolean isChangeFirstByteIndex = false;// 控制是否改变更改字体时的定位字节索引
        // 防止越界
        if (divideByte < 0) {
            divideByte = 0;
        } else if (divideByte > data.length) {
            divideByte = data.length - 1;
//            Log4an.d(TAG, "[拆分字节大于文件长度]divideByte=" + divideByte);
            isChangeFirstByteIndex = true;
        }
        divByte = divideByte;
//        Log4an.e(TAG, "divideByte=" + divideByte);
        int readLenth1 = 0;// 前一段文字实际读取的长度
        int readLenth2 = 0;// 后一段文字实际读取的长度

        try {
            IEncoding iEncoding = null;
            if (IEncoding.ENCODING_GBK.equalsIgnoreCase(encoding)) {
                iEncoding = new GBKEncoding();
                if (divideByte > 0) {
                    // Log4an.d(TAG, "【A1】start=" + 0 + ",end=" + (divideByte - 1));
                    readLenth1 = iEncoding.toChars(data, 0, divideByte - 1);
                    // Log4an.i(TAG, "【A2】readLenth1=" + readLenth1);
                    content[0] = new String(iEncoding.mValues);
                    // Log4an.i("yjd", "【content[0]】" + content[0]);
                    divideByte = readLenth1;
                }
                if (divideByte < data.length) {
                    // Log4an.d(TAG, "【B1】start=" + divideByte + ",end=" + (data.length));
                    readLenth2 = iEncoding.toChars(data, readLenth1, data.length);
                    // Log4an.i(TAG, "【B2】readLenth2=" + readLenth2);
                    content[1] = new String(iEncoding.mValues);
                    // Log4an.i("yjd", "【content[1]】" + content[1]);
                }
            } else if (IEncoding.ENCODING_UTF8.equalsIgnoreCase(encoding)) {
                iEncoding = new UTF8Encoding();
                if (divideByte > 0) {
                    // Log4an.i(TAG, "【3A】readLenth1=" + readLenth1);
                    readLenth1 = iEncoding.toChars(data, 0, divideByte - 1);
                    // Log4an.i(TAG, "【3B】readLenth1=" + readLenth1);
                    content[0] = new String(iEncoding.mValues);
                    // Log4an.i("yjd", "【content[0]】" + content[0]);
                    divideByte = readLenth1;
                }
                if (divideByte < data.length) {
                    // Log4an.i(TAG, "【4A】readLenth1=" + readLenth1 + ",divideByte=" + divideByte);
                    readLenth2 = iEncoding.toChars(data, divideByte, data.length);
                    // Log4an.i(TAG, "【4B】readLenth2=" + readLenth2);
                    content[1] = new String(iEncoding.mValues);
                    // Log4an.i("yjd", "【content[1]】" + content[1]);
                }
            } else {
                content[0] = new String(data, encoding);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        BookContentLineInfo line = null;
        // 换行：1：遇到\n 2,字数达到LineMaxNum:15字
        int lastLineEndCharIndex = 0; // 上一行最后一个字符的索引
        int lastLineEndByteIndex = startByte; // 上一行最后一个字节的索引
        boolean addParagraphSpaceTag = true;// 是否添加段间距标记(若遇到标题下面一行是""字符串时，置为false)
        boolean addParagraphStartTag = false;// 添加段落开始标记(to copy model)
        boolean isLastContent = false;// 更改字号时,首字符定位是否从上一段数据获取
        BookContentPaint paint = new BookContentPaint();
        for (int j = 0; j < content.length; j++) {
            // Log4an.e(TAG, "j=" + j);
            lastLineEndCharIndex = 0;
            if (!TextUtils.isEmpty(content[j])) {

                float[] widths = new float[content[j].length()];
                if (bookType == Constant.BOOKTYPE_ORDER_PAY) {
                    paint.changeStyleToPayTitle();
                } else {
                    paint.changeStyleToContent();
                }
                paint.getTextWidths(content[j], widths);

                int indentLength = 0;
                float curLineWidth = 0;
                final int BLANK_WIDTH = getStringWidth(paint, BLANK);
                boolean lastLineEndIsEnter = false;
                for (int i = 0; i < content[j].length(); i++) {

                    if (content[j].charAt(i) == '\n') {
                        // Log4an.d(TAG, "lastLineEndIsEnter=" + lastLineEndIsEnter);
                        if (lastLineEndIsEnter) {
                            lastLineEndCharIndex++;
                            lastLineEndByteIndex += getContentRealByteLength("\n", encoding);
                            lastLineEndIsEnter = true;
                            curLineWidth = 0;
                            indentLength = 0;
                            continue;
                        } else {
                            String srcContent = content[j].substring(lastLineEndCharIndex, i);
                            // Log4an.e(TAG, "【n】str=" + srcContent + ",str is null="
                            // + (srcContent == null ? true : srcContent.trim().length()));

                            if (srcContent != null && srcContent.trim().length() == 1) {
                                addParagraphSpaceTag = false;
                            }
                            if (srcContent != null && srcContent.trim().length() == 0) {
                                lastLineEndCharIndex += srcContent.length() + 1;
                                lastLineEndByteIndex +=
                                        (/* getContentRealByteLength(srcContent, encoding) + */getContentRealByteLength(
                                                "\n", encoding));
                                lastLineEndIsEnter = true;
                                curLineWidth = 0;
                                indentLength = 0;
                                continue;
                            }
                        }
                        line = new BookContentLineInfo();
                        line.setEnter(true);
                        list.add(line);
                        String srcContent = content[j].substring(lastLineEndCharIndex, i);
                        // Log4an.i(TAG, "1.indentLength=" + indentLength);
                        if (isTitle(srcContent)) {
                            indentLength = 0;
                        } else {
                            if (!TextUtils.isEmpty(srcContent) && srcContent.length() > 4
                                    && srcContent.startsWith(INDENT_STRING)) {
                                lastLineEndCharIndex += 2;
                                srcContent = content[j].substring(lastLineEndCharIndex, i);
                                // Log4an.d(TAG, "【A遇到多个空格】str=" + srcContent + ",str is null="
                                // + (srcContent == null ? true : srcContent.trim().length()));
                            } else if (srcContent.startsWith(BLANK)) {
                                lastLineEndCharIndex += getBlankCount(BLANK, srcContent);
                                // Log4an.w(TAG,
                                // "【a遇到BLANK】lastLineEndCharIndex=" + lastLineEndCharIndex
                                // + ",BLANK.length()=" + BLANK.length() * 2);
                                srcContent = content[j].substring(lastLineEndCharIndex, i);
                                indentLength = 2;
                                // Log4an.w(TAG, "【A遇到BLANK】srcContent=" + srcContent + ",len="
                                // + srcContent.length());
                            }
                        }
                        line.setContent(INDENT_STRING.substring(0, indentLength) + srcContent);
                        line.setFirstIndex(lastLineEndByteIndex);
                        line.setEndIndex(lastLineEndByteIndex
                                + getContentRealByteLength(srcContent, encoding) + 1);
                        line.setLineType(3);
                        // Log4an.i(TAG, "【1】" + line.getContent() + ",start=" +
                        // line.getFirstIndex()
                        // + ",end=" + line.getEndIndex() + ",linType=" + line.getLineType());
                        setXYS(line, widths, lastLineEndCharIndex, false, BLANK_WIDTH, indentLength);
                        lastLineEndCharIndex += srcContent.length() + 1;
                        lastLineEndByteIndex = line.getEndIndex() + 1;
                        indentLength = 0;
                        lastLineEndIsEnter = true;
                        curLineWidth = 0;

                        // 遇到段落结尾，添加段标记
                        if (addParagraphSpaceTag) {
                            line = new BookContentLineInfo();
                            line.setContent(PARAGRAPH_SPACE);
                            list.add(line);
                        }
                        addParagraphSpaceTag = true;
                        addParagraphStartTag = true;
                        continue;
                    }

                    if (lastLineEndIsEnter || i == 0) {// 如果上一行结束是'/n'换行符或者该段落是章节第一个段落
                        addParagraphStartTag = true;
                        lastLineEndIsEnter = false;
                        final int size =
                                lastLineEndCharIndex
                                        + Math.min(content[j].length() - 1 - lastLineEndCharIndex,
                                                INDENT_LENGTH);

                        for (int x = lastLineEndCharIndex; x < size; x++) {
                            if (!Character.isWhitespace(content[j].charAt(x))) {
                                indentLength = size - x;
                                curLineWidth += (BLANK_WIDTH * indentLength);
                                break;
                            }
                        }
                    }

                    // // // 宽度大于view宽度时，开始分行
                    curLineWidth +=
                            Character.isWhitespace(content[j].charAt(i)) ? BLANK_WIDTH : widths[i];
                    if (curLineWidth > viewWidth()) {

                        if ((errorChar.contains(content[j].charAt(i)))
                                && (i > 0 && !errorChar.contains(content[j].charAt(i - 1)))) {// 处理标点符号
                            line = new BookContentLineInfo();
                            list.add(line);
                            String srcContent = content[j].substring(lastLineEndCharIndex, i - 1);
                            if (srcContent.startsWith(INDENT_STRING)) {
                                lastLineEndCharIndex += 2;
                                srcContent = content[j].substring(lastLineEndCharIndex, i - 1);
                                addParagraphStartTag = true;
                                // Log4an.w(TAG, "【B标点遇到多个空格】srcContent=" + srcContent);
                            } else if (srcContent.startsWith(BLANK)) {
                                lastLineEndCharIndex += getBlankCount(BLANK, srcContent);
                                // Log4an.w(TAG,
                                // "【B遇到BLANK】lastLineEndCharIndex=" + lastLineEndCharIndex
                                // + ",BLANK.length()=" + BLANK.length() * 2);
                                srcContent = content[j].substring(lastLineEndCharIndex, i - 1);
                                indentLength = 2;
                                // Log4an.w(TAG, "【B遇到BLANK】srcContent=" + srcContent + ",len="
                                // + srcContent.length());
                            }

                            line.setContent(INDENT_STRING.substring(0, indentLength) + srcContent);
                            line.setFirstIndex(lastLineEndByteIndex);
                            line.setEndIndex(lastLineEndByteIndex
                                    + getContentRealByteLength(srcContent, encoding) - 1);
                            if (addParagraphStartTag) {
                                line.setLineType(2);
                            }
                            // Log4an.i(
                            // TAG,
                            // "【2】" + line.getContent() + ",start=" + line.getFirstIndex()
                            // + ",end=" + line.getEndIndex() + ",linType="
                            // + line.getLineType() + "indentLength=" + indentLength);
                            setXYS(line, widths, lastLineEndCharIndex, true, BLANK_WIDTH,
                                    indentLength);
                            lastLineEndCharIndex += srcContent.length();
                            lastLineEndByteIndex = line.getEndIndex() + 1;
                            addParagraphStartTag = false;
                            indentLength = 0;
                        } else {
                            line = new BookContentLineInfo();
                            list.add(line);
                            String srcContent = content[j].substring(lastLineEndCharIndex, i);

                            if (srcContent.startsWith(INDENT_STRING)) {
                                lastLineEndCharIndex += INDENT_STRING.length();
                                // Log4an.w(TAG, "【C遇到多个空格】lastLineEndCharIndex=" + srcContent
                                // + ",INDENT_STRING.length()=" + INDENT_STRING.length());
                                srcContent = content[j].substring(lastLineEndCharIndex, i);
                                // Log4an.w(TAG, "【C遇到多个空格】srcContent=" + srcContent);
                                addParagraphStartTag = true;
                                indentLength = 2;
                            } else if (srcContent.startsWith(BLANK)) {
                                lastLineEndCharIndex += getBlankCount(BLANK, srcContent);
                                // Log4an.w(TAG,
                                // "【C遇到BLANK】lastLineEndCharIndex=" + lastLineEndCharIndex
                                // + ",BLANK.length()=" + BLANK.length() * 2);
                                srcContent = content[j].substring(lastLineEndCharIndex, i);
                                indentLength = 2;
                                // Log4an.w(TAG, "【C遇到BLANK】srcContent=" + srcContent + ",len="
                                // + srcContent.length());
                            } else if (srcContent.startsWith("\\s")) {
                                // Log4an.d(TAG, "【C遇到\\s】str=" + srcContent + ",str is null="
                                // + (srcContent == null ? true : srcContent.trim().length()));
                                lastLineEndCharIndex += 2;
                                srcContent = content[j].substring(lastLineEndCharIndex, i);
                                addParagraphStartTag = true;
                                indentLength = 2;
                            } else if (srcContent.startsWith(" ")) {
                                // Log4an.d(TAG, "【C遇到英文空格】str=" + srcContent + ",str is null="
                                // + (srcContent == null ? true : srcContent.trim().length()));
                                lastLineEndCharIndex += getBlankCount(" ", srcContent);
                                srcContent = content[j].substring(lastLineEndCharIndex, i);
                                addParagraphStartTag = true;
                                indentLength = 2;
                            }
                            if (!isLastContent && !TextUtils.isEmpty(firstLineInfo)
                                    && firstLineInfo.length() > 2) {
                                // Log4an.e(TAG, "divByte=" + divByte + ",isChangeFirstByteIndex="
                                // + isChangeFirstByteIndex);
                                if (!isChangeFirstByteIndex && firstByteIndex != divByte) {
                                    firstByteIndex = divByte;
                                    // Log4an.e(TAG, "【赋值】firstByteIndex=" + firstByteIndex);
                                }
                                if (firstByteIndex >= lastLineEndByteIndex
                                        && firstByteIndex < (lastLineEndByteIndex
                                                + getContentRealByteLength(srcContent, encoding) - 1)) {
                                    // Log4an.w(
                                    // TAG,
                                    // "【匹配】firstByteIndex="
                                    // + firstByteIndex
                                    // + ",lastLineEndByteIndex="
                                    // + lastLineEndByteIndex
                                    // + ",endIndex="
                                    // + ((lastLineEndByteIndex
                                    // + getContentRealByteLength(srcContent,
                                    // encoding) - 1)) + ",str="
                                    // + srcContent);

                                    // Log4an.w(TAG, "【匹配】str=" + srcContent);
                                    // Log4an.d(TAG,
                                    // "【对比A】firstLineInfo=" + firstLineInfo
                                    // + ",firstByteIndex=" + firstByteIndex
                                    // + ",srcContent=" + srcContent
                                    // + ",srcContent.length()=" + srcContent.length());
                                    String s1 = firstLineInfo.substring(0, 2);
                                    // Log4an.d(TAG, "s1=" + s1 + ",s1Len=" + s1.length());
                                    if (srcContent.contains(s1)) {
                                        String str = srcContent.substring(srcContent.indexOf(s1));
                                        // Log4an.d(TAG, "【包括】str=" + str + ",strLen=" +
                                        // str.length()
                                        // + ",srcContent.length()=" + srcContent.length());
                                        int count = srcContent.length() - str.length();
                                        // Log4an.d(TAG, "count=" + count);
                                        lastLineEndByteIndex = firstByteIndex;
                                        lastLineEndCharIndex += count;
                                        i += count;
                                        // Log4an.d(TAG, "lastLineEndByteIndex="
                                        // + lastLineEndByteIndex + ",lastLineEndCharIndex="
                                        // + lastLineEndCharIndex + ",i=" + i);
                                        if (lastLineEndCharIndex < content[j].length()
                                                && i <= content[j].length()
                                                && lastLineEndCharIndex < i) {
                                            srcContent =
                                                    content[j].substring(lastLineEndCharIndex, i);
                                        }
                                        // Log4an.d(TAG, "【切割数据】srcContent=" + srcContent);
                                        // indentLength = 0;//此处注释掉
                                    }
                                }
                            }
                            if (isLastContent) {
                                indentLength = 0;
                                isLastContent = false;
                            }
                            line.setContent(INDENT_STRING.substring(0, indentLength) + srcContent);
                            line.setFirstIndex(lastLineEndByteIndex);
                            line.setEndIndex(lastLineEndByteIndex
                                    + getContentRealByteLength(srcContent, encoding) - 1);
                            if (addParagraphStartTag) {
                                line.setLineType(2);
                            }
                            // Log4an.i(
                            // TAG,
                            // "【3】" + line.getContent() + ",start=" + line.getFirstIndex()
                            // + ",end=" + line.getEndIndex() + ",linType="
                            // + line.getLineType() + ",indentLength=" + indentLength
                            // + ",len=" + srcContent.length());
                            setXYS(line, widths, lastLineEndCharIndex, true, BLANK_WIDTH,
                                    indentLength);
                            lastLineEndCharIndex += srcContent.length();
                            lastLineEndByteIndex = line.getEndIndex() + 1;
                            addParagraphStartTag = false;
                        }

                        indentLength = 0;
                        curLineWidth =
                                Character.isWhitespace(content[j].charAt(i)) ? BLANK_WIDTH
                                        : widths[i];

                        // 当剩余字数不足一行时
                        if ((i + 1) == content[j].length()) {


                            final String contentStr =
                                    content[j].substring(lastLineEndCharIndex, i + 1);

                            if (contentStr == null || isBlank(contentStr)) {
                                continue;
                            }
                            // Log4an.e(TAG, "【4】 lastLineEndByteIndex=" + lastLineEndByteIndex
                            // + ",divByte=" + divByte);
                            if (lastLineEndByteIndex == divByte) {
                                content[1] = contentStr + content[1];
                                // Log4an.e(TAG, "【4】 content[1]=" + content[1]);
                                setmCurLinesFirstByteIndex(divByte);
                                divByte = -1;
                                isLastContent = true;
                                break;
                            }


                            line = new BookContentLineInfo();
                            list.add(line);
                            curLineWidth = 0f;
                            line.setContent(contentStr);
                            line.setFirstIndex(lastLineEndByteIndex);
                            line.setEndIndex(lastLineEndByteIndex
                                    + getContentRealByteLength(line.getContent(), encoding));
                            // Log4an.i(
                            // TAG,
                            // "【4】" + line.getContent() + ",start=" + line.getFirstIndex()
                            // + ",end=" + line.getEndIndex() + ",linType="
                            // + line.getLineType());
                            setXYS(line, widths, lastLineEndCharIndex, false, BLANK_WIDTH,
                                    indentLength);
                            lastLineEndByteIndex = line.getEndIndex() + 1;
                            lastLineEndCharIndex += line.getContent().length();
                        }
                        continue;
                    }

                    if ((i + 1) == content[j].length()) {
                        String endSrcContent = content[j].substring(lastLineEndCharIndex, i + 1);

//                        Log4an.d(TAG, "1.endSrcContent=" + endSrcContent + "|firstLineInfo="
//                                + firstLineInfo + ",firstByteIndex=" + firstByteIndex + ",divByte="
//                                + divByte);

                        if (TextUtils.isEmpty(firstLineInfo)
                                && divByte >= lastLineEndByteIndex
                                && divByte < (lastLineEndByteIndex + getContentRealByteLength(
                                        endSrcContent, encoding))) {
                            content[1] = endSrcContent + content[1];
//                            Log4an.d("1", "首次进入阅读content[1]=" + content[1]);
                            break;
                        } else if (!TextUtils.isEmpty(firstLineInfo)
                                && firstLineInfo.length() > 2
                                && !TextUtils.isEmpty(endSrcContent)
                                && firstByteIndex != 0
                                && firstByteIndex >= lastLineEndByteIndex
                                && firstByteIndex < (lastLineEndByteIndex + getContentRealByteLength(
                                        endSrcContent, encoding))) {
//                            Log4an.d(TAG, "firstLineInfo=" + firstLineInfo);


                            String str1 = firstLineInfo.trim().substring(0, 1);
//                            Log4an.d(TAG, "str1=" + str1 + ",str1Len=" + str1.length());
                            String str2 = firstLineInfo.trim().substring(0, 2);
//                            Log4an.d(TAG, "str2=" + str2 + ",str2Len=" + str2.length());
                            boolean isCheck = false;
                            if (endSrcContent.contains(str2)) {
                                String endStr =
                                        endSrcContent.substring(endSrcContent.indexOf(str2));
                                endSrcContent =
                                        endSrcContent.substring(0, endSrcContent.indexOf(str2));
//                                Log4an.d(TAG, "endStr=" + endStr);
                                content[1] = endStr + content[1];
//                                Log4an.d("1", "Bcontent[1]=" + content[1]);
                                isCheck = true;
                            }
                            if (!isCheck && endSrcContent.contains(str1)) {
                                String endStr =
                                        endSrcContent.substring(endSrcContent.indexOf(str1));
                                endSrcContent =
                                        endSrcContent.substring(0, endSrcContent.indexOf(str1));
//                                Log4an.d(TAG, "endStr=" + endStr);
                                content[1] = endStr + content[1];
//                                Log4an.d("1", " Acontent[1]=" + content[1]);
                            }
//                            Log4an.d(TAG, "2.endSrcContent" + endSrcContent);
                            indentLength = 0;
                            isLastContent = true;
                        }
                        if (endSrcContent == null || isBlank(endSrcContent)) {
                            continue;
                        }

                        line = new BookContentLineInfo();
                        list.add(line);
                        // Log4an.i(TAG, "5.indentLength=" + indentLength);
                        line.setContent(INDENT_STRING.substring(0, indentLength) + endSrcContent);
                        line.setFirstIndex(lastLineEndByteIndex);
                        line.setEndIndex(lastLineEndByteIndex
                                + getContentRealByteLength(endSrcContent, encoding));
                        // Log4an.i(TAG, "【5】" + line.getContent() + ",start=" +
                        // line.getFirstIndex()
                        // + ",end=" + line.getEndIndex() + ",linType=" + line.getLineType());
                        setXYS(line, widths, lastLineEndCharIndex, false, BLANK_WIDTH, indentLength);
                        if (!isLastContent) {
                            lastLineEndByteIndex = line.getEndIndex() + 1;
                        } else {
                            lastLineEndByteIndex = line.getEndIndex();
                        }
                        lastLineEndCharIndex += endSrcContent.length();
                        indentLength = 0;
                        curLineWidth = 0;
                        continue;
                    }
                }
            }
        }
        if (list != null && list.size() > 0
                && PARAGRAPH_SPACE.equals(list.get(list.size() - 1).getContent())) {
            list.remove(list.get(list.size() - 1));
        }
        return list;
    }

    private int getContentRealByteLength(String content, String encoding) {
        try {
            if (encoding.equalsIgnoreCase("Unicode")) {
                return content.getBytes(encoding).length - 2; // 减去开头的BOM信息
            } else {
                return content.getBytes(encoding).length;
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return content.length();
    }

    private boolean isBlank(CharSequence str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    private boolean isWhitespace(char ch) {
        if (ch == '　') {
            return true;
        }
        if (Character.isWhitespace(ch)) {
            return true;
        }
        return false;
    }


    /** 设置每行字的x坐标 */
    /**
     * @param info
     * @param widths
     * @param start
     * @param isFillWidth
     * @param BLANK_WIDTH
     * @param indentLength
     */
    private void setXYS(BookContentLineInfo info, float[] widths, int start, boolean isFillWidth,
            int blankWidth, int indentLength) {

        final String content = info.getContent();
        if (content == null) {
            info.setXys(new float[0]);
            return;
        }
        final int contentLength = info.getContent().length();

        float[] xys = new float[contentLength * 2];
        info.setXys(xys);

        float space = 0;
        if (isFillWidth && contentLength > 0) {
            float contentWidth = blankWidth * indentLength;
            for (int j = 0; j < (contentLength - indentLength); j++) {
                contentWidth +=
                        (Character.isWhitespace(content.charAt(j + indentLength)) ? blankWidth
                                : widths[j + start]);
            }
            space =
                    (mBookContentRenderSetting.getScreenWidth() - contentWidth
                            - mBookContentRenderSetting.getMarginLeft()
                            - mBookContentRenderSetting.getMarginRight() - mBookContentRenderSetting
                                .getSideWidth()) / (contentLength - 1);

        }

        float x_offset = mBookContentRenderSetting.getMarginLeft();
        for (int j = 0; j < contentLength; j++) {
            if (j == 0) {
                info.getXys()[0] = mBookContentRenderSetting.getMarginLeft();
            } else {
                info.getXys()[j * 2] = x_offset;
            }
            x_offset +=
                    (Character.isWhitespace(content.charAt(j)) ? blankWidth : getTextWidth(widths,
                            j, start, indentLength, blankWidth) + space);
        }
    }

    private float getTextWidth(float[] widths, int j, int start, int indentLength, int blankWidth) {

        if (j < indentLength) {
            return blankWidth;
        }
        return widths[Math.min(j + start - indentLength, widths.length - 1)];
    }

    /**
     * 获取复制选取的内容 l
     * 
     * @return
     */
    public List<BookContentLineInfo> getCopyContentList() {
        // BookContentLineInfo lin=new BookContentLineInfo();
        // lin.setContent("hahahahahahahahahaha");
        // lin.setLineType(0);
        // copyContentList.add(lin);
        return copyContentList;
    }
}
